package cn.murky.tenant.system.biz.mq;

import cn.murky.common.domain.dto.SchemaInitDTO;
import cn.murky.core.exception.ServiceException;
import cn.murky.folkmq.constant.SysGroupConstant;
import cn.murky.tenant.core.SecurityTenantUserInfo;
import cn.murky.tenant.core.utils.SecurityUtils;
import cn.murky.tenant.system.biz.domian.entity.SysDept;
import lombok.extern.slf4j.Slf4j;
import org.noear.redisx.RedisClient;
import org.noear.snack.ONode;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.cloud.CloudEventHandler;
import org.noear.solon.cloud.annotation.CloudEvent;
import org.noear.solon.cloud.model.Event;
import org.noear.solon.data.annotation.TranAnno;
import org.noear.solon.data.tran.TranUtils;

import static cn.murky.folkmq.constant.SysTopicConstant.TENANT_INIT_TOPIC;
import static cn.murky.tenant.system.api.constant.ErrorConstant.INIT_TENANT_DATA_ERROR;

/**
 * 用来处理租户模式创建后的初始化数据事件
 */
@Slf4j
@Component
@CloudEvent(topic = TENANT_INIT_TOPIC, group = SysGroupConstant.DEFAULT)
public class SchemaInitMqTemplate implements CloudEventHandler {
    @Inject
    private RedisClient redisClient;
    private void initSchema(SchemaInitDTO schemaInitDTO){
        SecurityTenantUserInfo securityTenantUserInfo = new SecurityTenantUserInfo().setTenantId(schemaInitDTO.getId());
        SecurityUtils.runnable(securityTenantUserInfo,()->{
            boolean save = new SysDept()
                    .setDeptName(schemaInitDTO.getTenantName())
                    .setSort(0)
                    .setParentId(0L).save();
            if (!save) {
                throw new ServiceException(INIT_TENANT_DATA_ERROR);
            }
        });
    }

    @Override
    public boolean handle(Event event) throws Throwable {
        // 分布式锁,在集群环境下防止重复刷新缓存
        SchemaInitDTO schemaInitDTO = ONode.deserialize(event.content(), SchemaInitDTO.class);
        if (redisClient.getLock(STR."\{TENANT_INIT_TOPIC}:LOCK:\{schemaInitDTO.getId()}").tryLock(5)) {
            log.info("[SchemaInitMqTemplate] -> 消费消息 -> topic:{},msg:{}", event.topic(), event.content());
            try {
                TranUtils.execute(new TranAnno(), ()->{
                    initSchema(schemaInitDTO);
                });
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }

        }
        return true;
    }
}
